package com.lazi.june.web.exception;

import com.lazi.june.common.base.Result;
import com.lazi.june.common.exception.CommonException;
import com.lazi.june.common.exception.ExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.resource.NoResourceFoundException;

/**
 * desc:
 *
 * @author huliqian
 * @since 2025/8/21
 */
@Slf4j
@Order(10000)
@RestControllerAdvice
public class CommonExceptionHandler {


    @ExceptionHandler({CommonException.class})
    @ResponseStatus(HttpStatus.OK)
    public Result<?> bizException(CommonException ex) {
        log.warn(ex.getMessage(), ex);
        return Result.error(ex.getCode(), ex.getMessage());
    }

    @ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.OK)
    public Result<?> methodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("参数校验失败,ex = {}", e.getMessage(), e);
        FieldError fieldError = e.getBindingResult().getFieldError();
        assert fieldError != null;
        return Result.error(ExceptionEnum.ERROR_PARAM_VALID.getCode(), fieldError.getField() + "::" + fieldError.getDefaultMessage());
    }


    @ExceptionHandler({NoResourceFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Result<?> notFoundExceptionHandler(NoResourceFoundException e) {
        log.info("请求路径 404 {}", e.getMessage());
        return Result.error(ExceptionEnum.ERROR_RESOURCE_NOT_FOUND.getCode(), e.getMessage());
    }


    @ExceptionHandler({ServletRequestBindingException.class})
    @ResponseStatus(HttpStatus.OK)
    public Result<?> servletRequestBindingException(ServletRequestBindingException e) {
        log.error("参数校验失败,ex = {}", e.getMessage(), e);
        return Result.error(ExceptionEnum.ERROR_PARAM_VALID.getCode(), e.getMessage());
    }

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.OK)
    public Result<?> handleIllegalArgumentException(IllegalArgumentException e) {
        log.error("非法参数,ex = {}", e.getMessage(), e);
        return Result.error(ExceptionEnum.SYSTEM_UNKNOWN.getCode(), e.getMessage());
    }


    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result<?> handleGlobalException(Exception e) {
        log.error("全局异常信息 ex={}", e.getMessage(), e);
        return Result.error(ExceptionEnum.SYSTEM_UNKNOWN.getCode(), e.getMessage());
    }
}
